jQuery.validator.addMethod("postalCodeValid", function (value, element) {
    if (!$.regexpCommon('postalCode').test($.trim(value))) {
        return false;
    }
    return true;
}, "<Strong>Error:</Strong> Please input Correct Contact Postal Code.");
jQuery.validator.addMethod("phoneNumberValid", function (value, element) {
    if (!$.regexpCommon('phoneNumber').test($.trim(value))) {
        return false;
    }
    return true;
}, "<Strong>Error:</Strong> Please input Correct Contact Phone Number.");

jQuery.validator.addMethod("extendEmailValid", function (value, element) {
    if (!(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i).test($.trim(value))) {
        return false;
    }
    var content = value.split(".");
    for (var j = 0; j < content.length; j++) {
        if (content[j].length > 63) {
            return false;
        }
    }
    return true;
}, "<Strong>Error:</Strong> Email must be an email address.");

function FormatPhone(control) {
    if (control.value != "") {
        control.value = FormatPhoneNumber(control.value);
    }
}

function FormatPhoneNumber(phoneNumber) {
    if (phoneNumber) {
        var phone = phoneNumber.replace(/\D/g, "").replace(/^[01]{1,}/, "");
        if (phone.length > 10)
            phone = phone.substr(0, 10);
        if (phone.length == 10)
            return "(" + phone.substring(0, 3) + ") " + phone.substring(3, 6) + "-" + phone.substring(6);
        else
            return phone;
    }
}
function getThirtyDaysAgoDate(date) {
    date.setDate(date.getDate() - 30);
    return date;
}

function getFromDate(date) {
    date.setHours(23);
    date.setMinutes(59);
    date.setSeconds(59);
    date.setMilliseconds(999);
    return date;
}

function formatFromDateTime(date) {
    if (date == null || date == '') {
        return date;
    }
    return date.concat("T00:00:00");
}

function formatToDateTime(date) {
    if (date == null || date == '') {
        return date;
    }
    return date.concat("T23:59:59");
}

function format(time, format) {
    var hour = time.getHours();
    if (/(a+)/.test(format)) {
        if (hour == 0) {
            hour = 12;
        } else if (hour > 12) {
            hour = hour - 12;
        }
    }

    var arr = {
        "M+": time.getMonth() + 1, //month
        "d+": time.getDate(), //day
        "h+": hour, //hour
        "m+": time.getMinutes()
    };
    if (/(y+)/.test(format)) {
        format = format.replace(RegExp.$1, (time.getFullYear() + "").substr(4 - RegExp.$1.length));
    }

    if (/(a+)/.test(format)) {
        format = format.replace(RegExp.$1, ((parseInt(time.getHours()) < parseInt(12) ? "AM" : "PM") + "").substr(2 - RegExp.$1.length));
    }

    for (var k in arr) {
        if (new RegExp("(" + k + ")").test(format)) {
            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? arr[k] : ("00" + arr[k]).substr(("" + arr[k]).length));
        }
    }
    return format;
}

function getVendorByAjaxSubmit(object) {
    var vendorMsg = $.trim($(object).val());
    $("#vendorSelect").find("option").remove();
    if (vendorMsg.length < 2) {
        return false;
    }
    $("#getVendorForm").ajaxSubmit({
        callback: function (data) {
            $("#vendorSelect").find("option").remove();
            if ($("#vendorMessage").val().length < 2) {
                return;
            }
            var vendorList = data.vendorList;
            for (var i = 0; i < vendorList.length; i++) {
                if ($("#vendor_select_" + vendorList[i].vendorNumber).length == 0) {
                    $("<option id='vendor_select_" + vendorList[i].vendorNumber + "' value='" + vendorList[i].vendorNumber + "'>" + vendorList[i].vendorName + "</option>").appendTo("#vendorSelect");
                }
            }
            if (vendorList.length != $("#vendorSelect").find("option").length) {
                $("#vendorSelect").find("option").remove();
                for (var i = 0; i < vendorList.length; i++) {
                    if ($("#vendor_select_" + vendorList[i].vendorNumber).length == 0) {
                        $("<option id='vendor_select_" + vendorList[i].vendorNumber + "' value='" + vendorList[i].vendorNumber + "'>" + vendorList[i].vendorName + "</option>").appendTo("#vendorSelect");
                    }
                }
            }
        }
    });
}


$(document).ajaxComplete(function (event, xhr, settings) {
    doAfterForbiden(xhr);
});


function doAfterForbiden(xhr) {
    if (xhr.status == 401) {
        location.reload();
        xhr.abort();
    }

}


(function ($) {
    var Form = {
        serialize: function (form, serializers) {
            var $form = $(form);
            $form.find(":disabled").attr("data-disabled", "true").removeAttr("disabled");

            var checkbox = $form.find("input:checkbox");

            checkbox.each(function () {
                var $this = $(this);

                if ($this.is(":checked")) {
                    $this.attr("data-checked", "true");
                    if ($this.val() == null || $this.val() == 'on') {
                        $this.val("true");
                    }
                } else {
                    $this.attr("data-value", $this.val());
                    $this.val("false");
                    $this.attr("checked", "checked");
                }
            });

            var a = $form.serializeArray();

            $form.find("[data-disabled='true']").attr("disabled", "disabled");
            $form.find("[data-disabled='true']").removeAttr("data-disabled");

            checkbox.each(function () {
                var $this = $(this);

                if ($this.attr("data-checked")) {
                    $this.removeAttr("data-checked");
                } else {
                    $this.removeAttr("checked");
                    $this.attr("value", $this.attr("data-value"));
                    $this.removeAttr("data-value");
                }
            });

            var o = {};

            $.each(a, function () {
                if (serializers[this.name] != undefined) {
                    o[this.name] = serializers[this.name](this.value, o[this.name]);
                } else {
                    if (o[this.name] !== undefined) {
                        if (!o[this.name].push) {
                            o[this.name] = [o[this.name]];
                        }
                        o[this.name].push(this.value || '');
                    } else {

                        o[this.name] = this.value || '';
                    }
                }
            });

            return o;
        },

        dispatcher: function (form, options, data) {
            var $form = $(form);
            var dispatcher = {};

            if ($.isFunction(options.callback)) {
                dispatcher.callback = options.callback;
            } else {
                var callback = $form.data("callback");

                if (callback) {
                    if (callback.match("^redirect:")) {
                        var url = callback.substring("redirect:".length).trim();

                        if (url) {
                            dispatcher.callback = function () {
                                window.location.href = Form.renderURL(url, data);
                            }
                        } else {
                            dispatcher.callback = function () {
                            };
                        }
                    } else {
                        dispatcher.callback = eval(callback);
                    }
                } else {
                    dispatcher.callback = function () {
                    };
                }
            }

            if ($.isFunction(options.handler)) {
                dispatcher.handler = options.handler;
            } else {
                var handler = $form.data("handler");
                if (handler) {
                    dispatcher.handler = eval(handler);
                } else {
                    dispatcher.handler = function () {
                    }
                }
            }

            return dispatcher;
        },

        renderURL: function (url, data) {
            var fn = ( function () {
                var start = "{", end = "}", path = "[a-z0-9_$][\\.a-z0-9_]*", // e.g. config.person.name
                    pattern = new RegExp(start + "\\s*(" + path + ")\\s*" + end, "gi"), undef;

                return function (template, data) {
                    return template.replace(pattern, function (tag, token) {
                        var path = token.split("."), len = path.length, lookup = data, i = 0;

                        for (; i < len; i++) {
                            lookup = lookup[path[i]];

                            if (lookup === undef) {
                                throw "tim: '" + path[i] + "' not found in " + tag;
                            }

                            if (i === len - 1) {
                                return lookup;
                            }
                        }
                    });
                };
            }());

            return fn(url, data);
        }
    }
    $.fn.extend({
        ajaxForm: function (opt) {
            return this.each(function () {
                var form = this;
                var $form = $(form);

                var options = $.extend({
                    method: $form.attr("method"),
                    action: $form.attr("action"),
                    validate: true,
                    serializers: {}
                }, opt);

                if (options.validate) {
                    $form.validate();
                }

                $(this).submit(function (e) {
                    e.stopPropagation();
                    e.preventDefault();
                    $form.ajaxSubmit(options);
                });
            });
        },

        ajaxSubmit: function (opt) {
            var form = this;
            var $form = $(form);

            var options = $.extend({
                method: $form.attr("method"),
                action: $form.attr("action"),
                validate: true,
                serializers: {}
            }, opt);

            var validator = $form.data("validator");
            if (validator) {
                validator.checkForm();
                if (!validator.valid()) {
                    validator.showErrors();
                    return;
                }
            }

            $.ajax({
                type: options.method,
                url: options.action,
                contentType: "application/json; charset=utf-8",
                data: JSON.stringify(Form.serialize(form, options.serializers)),
                dataType: "json",
                context: form,
                complete: function (xhr) {
                    doAfterForbiden(xhr);

                    var data = JSON.parse(xhr.responseText);
                    var dispatcher = Form.dispatcher(this, options, data);

                    if (xhr.status == 301 || xhr.status == 200 || xhr.status == 201) {
                        dispatcher.callback.call(form, data, xhr.status);
                    } else if (xhr.status == 400 && validator) {
                        var errors = {};
                        $.each(data["field_errors"], function (index, obj) {
                            errors[obj.field] = obj.message;
                        });
                        validator.showErrors(errors);
                    } else {
                        dispatcher.handler.call(form, data, xhr.status);
                    }
                }
            });
        }
    });

})(jQuery);

/**
 * Date.parse with progressive enhancement for ISO 8601 <https://github.com/csnover/js-iso8601>
 * © 2011 Colin Snover <http://zetafleet.com>
 * Released under MIT license.
 */
(function (Date, undefined) {
    var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ];
    Date.parse = function (date) {
        var timestamp, struct, minutesOffset = 0;

        // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
        // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
        // implementations could be faster
        //              1 YYYY                2 MM       3 DD           4 HH    5 mm       6 ss        7 msec        8 Z 9 ±    10 tzHH    11 tzmm
        if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) {
            // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
            for (var i = 0, k; (k = numericKeys[i]); ++i) {
                struct[k] = +struct[k] || 0;
            }

            // allow undefined days and months
            struct[2] = (+struct[2] || 1) - 1;
            struct[3] = +struct[3] || 1;

            if (struct[8] !== 'Z' && struct[9] !== undefined) {
                minutesOffset = struct[10] * 60 + struct[11];

                if (struct[9] === '+') {
                    minutesOffset = 0 - minutesOffset;
                }
            }

            timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
        }
        else {
            timestamp = origParse ? origParse(date) : NaN;
        }

        return timestamp;
    };
}(Date));
